package com.xcity.game.activity.cumulativerecharge;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.List;

import com.alibaba.fastjson.JSONObject;
import com.xcity.db.entity.Player;
import com.xcity.game.activity.ActivityService;
import com.xcity.game.activity2.ActivityIds;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.common.PlayerPool;
import com.xcity.game.event.GameEvents;
import com.xcity.game.item.ItemTemplate;
import com.xcity.game.item.drop.listener.MultiDropAdapter;
import com.xcity.game.item.listener.BagListener;
import com.xcity.game.player.PlayerService;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.push.msg.ActivityStatePush;
import com.xcity.pomelo.push.msg.BatchItemsPush;
import com.xcity.pomelo.request.CumulativeGetRequest;
import com.xcity.pomelo.request.CumulativeListRequest;
import com.xcity.pomelo.response.CumulativeGetResponse;
import com.xcity.pomelo.response.CumulativeListResponse;
import com.xcity.pomelo.response.HintResponse;

import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.template.TemplateService;
import naga.x.game.time.DayListener;
import naga.x.game.time.TimeUpdater;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.ServiceException;
import naga.x.util.TimeUtils;

@OPHandler
public class CumulativeRechargeActivityService extends ActivityService implements EventListener, DayListener{
	
	protected int beginDay = TimeUtils.ofDay(TimeUtils.parse("yyyy-MM-dd", "2017-09-15").getTime());
	
	public static int ACTIVE_DAY_NEWROLE = 6;//6;
	public static int REWARD_DAY_NEWROLE = 7;//7;
	public static int ACTIVE_DAY = 6;//6;
	public static int REWARD_DAY = 7;//7;
	
	public static boolean active = false;
	public static boolean newRoleActive = true;//TODO
	
	protected List<CumulativeRechargeTemplate> rechargeList;

	@Override
	public void startup() throws ServiceException {
		initTemp();
		App.getApp().getEventManager().register(this);
		TimeUpdater.getInstance().addDayListener(this);
		updateActive(TimeUpdater.getInstance().today());
	}
	
	public void initTemp(){
		rechargeList = App.getApp().getServiceManager().get(TemplateService.class).getTemplatesList(CumulativeRechargeTemplate.class);
	}

	@Override
	public void shutdown() throws ServiceException {
	}

	@Override
	public int[] getEventTypes() {
		return new int[]{
			GameEvents.EVENT_PLAYER_LOGIN,
			GameEvents.EVENT_PLAYER_LOADED,
			GameEvents.EVENT_RECHARGE,
			GameEvents.EVENT_RECHARGE_OFFLINE,
		};
	}

	@Override
	public void handleEvent(Event event) {
		switch (event.getType()) {
		case GameEvents.EVENT_PLAYER_LOADED:
			playerLoaded(event.getParameter(0));
			break;
		case GameEvents.EVENT_PLAYER_LOGIN:
			playerLogin(event.getParameter(0));
			break;
		case GameEvents.EVENT_RECHARGE:
		case GameEvents.EVENT_RECHARGE_OFFLINE:
			handleRecharge((Player)event.getParameter(0), (int)event.getParameter(1));
			break;
		default:
			break;
		}
	}

	public void playerLoaded(Player player){
		if(checkInNewRoleActive(player)){
			player.send(new ActivityStatePush(ActivityIds.ACTIVITY_CUMULATIVE, STATE_OPENED));
		}else if(active){
			player.send(new ActivityStatePush(ActivityIds.ACTIVITY_CUMULATIVE, STATE_OPENED));
		}
	}

	@Override
	public boolean dayChanged() {
		boolean oldActive = active;
		int today = TimeUpdater.getInstance().today();
		updateActive(today);
		if(oldActive != active){
			if(active){
				Collection<Player> players = App.getApp().getServiceManager().get(PlayerService.class).getOnlinePlayers();
				for(Player player : players){
					if(!TimeUtils.checkDayDuring(player.getNewPlayerTasks().getCreatDay(), today, REWARD_DAY_NEWROLE + 1)){//today > player.getNewPlayerTasks().getCreatDay() + REWARD_DAY
						//yesterday == createDay + REWARD_DAY -> opened
						player.send(new ActivityStatePush(ActivityIds.ACTIVITY_CUMULATIVE, STATE_OPENED));
					}
				}
			}else{
				Collection<Player> players = App.getApp().getServiceManager().get(PlayerService.class).getOnlinePlayers();
				for(Player player : players){
					if(!TimeUtils.checkDayDuring(player.getNewPlayerTasks().getCreatDay(), today, REWARD_DAY_NEWROLE)){//today >= player.getNewPlayerTasks().getCreatDay() + REWARD_DAY
						//today == createDay + REWARD_DAY -> closed
						player.send(new ActivityStatePush(ActivityIds.ACTIVITY_CUMULATIVE, STATE_CLOSED));
					}
				}
			}
		}
		return true;
	}
	public void playerLogin(Player player){
	}
	
	public void updateActive(int today){
		if(TimeUtils.checkDayDuring(beginDay, today, REWARD_DAY) && today >= beginDay){//today < beginDay + REWARD_DAY
			active = true;
		}else{
			active = false;
		}
	}
	
	public CumulativeRechargeTemplate getTemplateById(int id){
		for(int i = rechargeList.size() - 1; i > -1; i--){
			if(rechargeList.get(i).getId() == id){
				return rechargeList.get(i);
			}
		}
		return null;
	}
	
	public boolean checkInNewRoleActive(Player player){
		if(!newRoleActive){
			return false;
		}
		int creatDay = player.getNewPlayerTasks().getCreatDay();
		int today = TimeUpdater.getInstance().today();
		if(TimeUtils.checkDayDuring(creatDay, today, REWARD_DAY_NEWROLE)){//today < creatDay + REWARD_DAY
			return true;
		}
		return false;
	}
	public void handleRecharge(Player player, int money){
		int lastDay = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_BEGIN_DAY, 0);
		int creatDay = player.getNewPlayerTasks().getCreatDay();
		int today = TimeUpdater.getInstance().today();
		int chargedMoney = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, 0);
		JSONObject map = player.getPool().getJSONObject(PlayerPool.PROPERTY_CUMULATIVE_RECORD);
		if(map == null){
			map = new JSONObject();
		}
		if(TimeUtils.checkDayDuring(creatDay, today, REWARD_DAY_NEWROLE)){//today < creatDay + REWARD_DAY
			//在新手活动期间内
			if(lastDay != creatDay || lastDay == 0){
				//清除数据
				map.clear();
				player.poolSet(PlayerPool.PROPERTY_CUMULATIVE_RECORD, map);
				chargedMoney = 0;
				player.getPool().put(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, chargedMoney);
				player.getPool().put(PlayerPool.PROPERTY_CUMULATIVE_BEGIN_DAY, creatDay);
			}
			if(TimeUtils.checkDayDuring(creatDay, today, ACTIVE_DAY_NEWROLE)){//today < creatDay + ACTIVE_DAY
				player.getPool().put(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, chargedMoney + money);
			}
		}else{
			//非新手活动期间
			if(lastDay != beginDay){//today > beginDay + REWARD_DAY || today < beginDay || 
				//不是本次活动 清除数据
				map.clear();
				player.poolSet(PlayerPool.PROPERTY_CUMULATIVE_RECORD, map);
				chargedMoney = 0;
				player.getPool().put(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, chargedMoney);
				player.getPool().put(PlayerPool.PROPERTY_CUMULATIVE_BEGIN_DAY, beginDay);
			}
			if(TimeUtils.checkDayDuring(beginDay, today, ACTIVE_DAY) && today >= beginDay){//today < beginDay + ACTIVE_DAY
				player.getPool().put(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, chargedMoney + money);
			}
		}
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_CUMULATIVE_RECHARGE_LIST)
	public void requestCumulativeList(Session session, CumulativeListRequest req){
		Player player = session.getClient();
		int type = 0;
		if(checkInNewRoleActive(player)){
			type = 1;
		}
		int today = TimeUpdater.getInstance().today();
		if(type == 0){
			if(!active){
				player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_ACTIVE));
				return;
			}
			JSONObject map = player.getPool().getJSONObject(PlayerPool.PROPERTY_CUMULATIVE_RECORD);
			if(map == null){
				map = new JSONObject();
			}
			int lastDay = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_BEGIN_DAY, 0);
			int chargedMoney = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, 0);
			boolean isEnd = true;
			if(lastDay != beginDay){
				map.clear();
				chargedMoney = 0;
			}
			if(TimeUtils.checkDayDuring(beginDay, today, ACTIVE_DAY) && today >= beginDay){//today < beginDay + ACTIVE_DAY
				isEnd = false;
			}
			player.send(new CumulativeListResponse(req.getSerial(), type, rechargeList, map, chargedMoney, isEnd, beginDay));
		}else{
			JSONObject map = player.getPool().getJSONObject(PlayerPool.PROPERTY_CUMULATIVE_RECORD);
			if(map == null){
				map = new JSONObject();
			}
			int lastDay = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_BEGIN_DAY, 0);
			int chargedMoney = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, 0);
			int createDay = player.getNewPlayerTasks().getCreatDay();
			if(lastDay != createDay){
				map.clear();
				chargedMoney = 0;
			}
			boolean isEnd = true;
			if(TimeUtils.checkDayDuring(createDay, today, ACTIVE_DAY_NEWROLE) && today >= createDay){//today < createDay + ACTIVE_DAY
				isEnd = false;
			}
			player.send(new CumulativeListResponse(req.getSerial(), type, rechargeList, map, chargedMoney, isEnd, createDay));
		}
	}
	
	@PomeloOP(PomeloRoute.ACTIVITY_CUMULATIVE_RECHARGE_GET)
	public void requestCumulativeRechargeGet(Session session, CumulativeGetRequest req){
		Player player = session.getClient();
		CumulativeRechargeTemplate temp = getTemplateById(req.getId());
		if(temp == null){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_REWARD));
			return;
		}
		if(temp.getNeed() == 0){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_REWARD));
			return;
		}
		int type = temp.getType();
		int lastDay = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_BEGIN_DAY, 0);
		int chargedMoney = player.getPool().getInt(PlayerPool.PROPERTY_CUMULATIVE_RECHARGE_MONEY, 0);
		if(type == 1){
			int createDay = player.getNewPlayerTasks().getCreatDay();
			if(lastDay != createDay){
				player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_ACTIVE));
				return;
			}
			if(!checkInNewRoleActive(player)){
				player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_ACTIVE));
				return;
			}
		}else{
			if(lastDay != beginDay){
				player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_ACTIVE));
				return;
			}
			if(!active){
				player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_ACTIVE));
				return;
			}
		}
		if(chargedMoney < temp.getNeed()){
			player.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_NO_REWARD, temp.getNeed() - chargedMoney)));
			return;
		}
		JSONObject map = player.getPool().getJSONObject(PlayerPool.PROPERTY_CUMULATIVE_RECORD);
		if(map == null){
			map = new JSONObject();
		}
		if(map.getIntValue(String.valueOf(temp.getId())) == 1){
			player.send(new HintResponse(req.getSerial(), MessageConst.ACTIVITY_CUMULATIVE_RECHARGE_ALREADY_GET));
			return;
		}
		//发奖励
//		MailAttach attach = new MailAttach();
//		String title = "累计充值活动奖励";
//		String content = "恭喜获得累计充值活动奖励";
//		if(temp.getMoney() > 0){
//			attach.setGold(temp.getMoney());
//		}
//		for(int i = 0; i < temp.getItemIds().length; i++){
//			attach.addItem(temp.getItemIds()[i], temp.getItemCounts()[i]);
//		}
//		App.getApp().getServiceManager().get(MailService.class).sendSystemMail(player.getId(), title, content, attach);
		
		int itemCount = temp.getItemIds().length;
		final BatchItemsPush sync = new BatchItemsPush(itemCount + 1);
		if(temp.getMoney() > 0){
			player.addGold(temp.getMoney(), Cause.CUMULATIVE_GET);
			sync.addGold(temp.getMoney());
		}
		BagListener bagLsr = new MultiDropAdapter() {
			@Override
			public void itemAdded(ItemTemplate item, int count) {
				sync.add(item, count);
			}
		};
		for(int i = 0; i < itemCount; i++){
			player.getBag().addItemOrSendMail(temp.getItemIds()[i], temp.getItemCounts()[i], Cause.CUMULATIVE_GET, bagLsr);
		}
		//加次数
		map.put(String.valueOf(temp.getId()), 1);
		player.poolSet(PlayerPool.PROPERTY_CUMULATIVE_RECORD, map);
		player.send(new CumulativeGetResponse(req.getSerial(), temp.getId()));
		player.send(sync);
		LOG.info("[CUMULATIVE]ID[{}]CAUSE[{}]", player.getId(), Cause.CUMULATIVE_GET);
	}
	
	@Deprecated
	public void setBeginDay(String date){
		try {
			beginDay = TimeUtils.ofDay(TimeUtils.parse("yyyy-MM-dd", date).getTime());
			int today = TimeUpdater.getInstance().today();
			updateActive(today);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
